all files / internal/ touchRipple.vue

28.13% Statements 18/64
33.33% Branches 12/36
15.38% Functions 2/13
6.52% Lines 3/46
7 statements, 6 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126                    1× 1×                                                                                                                                                                                                                                    
//
//
//
//
//
//
//
//
//
 
import circleRipple from './circleRipple'
import * as domUtil from '../utils/domUtil'
export default {
  props: {
    centerRipple: {
      type: Boolean,
      default: true
    },
    rippleWrapperClass: {
    },
    color: {
      type: String,
      default: ''
    },
    opacity: {
      type: Number
    }
  },
  data () {
    return {
      nextKey: 0,
      ripples: []
    }
  },
  mounted () {
    this.ignoreNextMouseDown = false
  },
  methods: {
    start (event, isRippleTouchGenerated) {
      if (this.ignoreNextMouseDown && !isRippleTouchGenerated) {
        this.ignoreNextMouseDown = false
        return
      }
      this.ripples.push({
        key: this.nextKey++,
        color: this.color,
        opacity: this.opacity,
        style: this.centerRipple ? {} : this.getRippleStyle(event)
      })
      this.ignoreNextMouseDown = isRippleTouchGenerated
    },
    end () {
      if (this.ripples.length === 0) return
      this.ripples.splice(0, 1)
      this.stopListeningForScrollAbort()
    },
    stopListeningForScrollAbort () {
      if (!this.handleMove) this.handleMove = this.handleTouchMove.bind(this)
      document.body.removeEventListener('touchmove', this.handleMove, false)
    },
    startListeningForScrollAbort (event) {
      this.firstTouchY = event.touches[0].clientY
      this.firstTouchX = event.touches[0].clientX
      document.body.addEventListener('touchmove', this.handleMove, false)
    },
    handleMouseDown (event) {
      if (event.button === 0) {
        this.start(event, false)
      }
    },
    handleTouchStart (event) {
      if (event.touches) {
        this.startListeningForScrollAbort(event)
        this.startTime = Date.now()
      }
      this.start(event.touches[0], true)
    },
    handleTouchMove (event) {
      const deltaY = Math.abs(event.touches[0].clientY - this.firstTouchY)
      const deltaX = Math.abs(event.touches[0].clientX - this.firstTouchX)
      // 判断滚动 6px
      if (deltaY > 6 || deltaX > 6) this.end()
      // const timeSinceStart = Math.abs(Date.now() - this.startTime)
      // if (timeSinceStart > 300) {
      //   this.stopListeningForScrollAbort()
      //   return
      // }
    },
    getRippleStyle (event) {
      const el = this.$refs.holder
      const elHeight = el.offsetHeight
      const elWidth = el.offsetWidth
      const offset = domUtil.getOffset(el)
      const isTouchEvent = event.touches && event.touches.length
      const pageX = isTouchEvent ? event.touches[0].pageX : event.pageX
      const pageY = isTouchEvent ? event.touches[0].pageY : event.pageY
      const pointerX = pageX - offset.left
      const pointerY = pageY - offset.top
      const topLeftDiag = this.calcDiag(pointerX, pointerY)
      const topRightDiag = this.calcDiag(elWidth - pointerX, pointerY)
      const botRightDiag = this.calcDiag(elWidth - pointerX, elHeight - pointerY)
      const botLeftDiag = this.calcDiag(pointerX, elHeight - pointerY)
      const rippleRadius = Math.max(
        topLeftDiag, topRightDiag, botRightDiag, botLeftDiag
      )
      const rippleSize = rippleRadius * 2
      const left = pointerX - rippleRadius
      const top = pointerY - rippleRadius
      return {
        directionInvariant: true,
        height: rippleSize + 'px',
        width: rippleSize + 'px',
        top: top + 'px',
        left: left + 'px'
      }
    },
    calcDiag (a, b) {
      return Math.sqrt((a * a) + (b * b))
    }
  },
  components: {
    'circle-ripple': circleRipple
  }
}